//
//  HelloWorldLayer.m
//  CatRace
//
//  Created by Ray Wenderlich on 4/23/11.
//  Copyright __MyCompanyName__ 2011. All rights reserved.
//


// Import the interfaces
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#import "RootViewController.h"

// HelloWorldLayer implementation
@implementation HelloWorldLayer
@synthesize currentLeaderBoard;

//Leaderboard Category IDs
#define kLeaderboardID @"1"

//Achievement IDs
#define kAchievementOneTap @"1_Tap"
#define kAchievement20Taps @"20_Taps"
#define kAchievementWin5Times @"Win5Times"
#define kAchievementGoal1 @"Goal1"

//Leaderboard Category IDs
#define kEasyLeaderboardID @"com.appledts.EasyTapList"
#define kHardLeaderboardID @"com.appledts.HardTapList"
#define kAwesomeLeaderboardID @"com.appledts.AwesomeTapList"


//Achievement IDs
#define kAchievementGotOneTap @"com.appletest.one_tap"
#define kAchievementHidden20Taps @"com.appledts.twenty_taps"
#define kAchievementBigOneHundred @"com.appledts.one_hundred_taps"

#pragma mark Send Message Data
- (void)sendData:(NSData*)data{
    NSError* error;
    BOOL success = [[GCHelper sharedInstance].match sendDataToAllPlayers:data
                                                            withDataMode:GKMatchSendDataReliable 
                                                                   error:&error];
    if(!success)
    {
        NSLog(@"Error sending init packet");
        [self matchEnded];
    }
}

- (void) sendRandomNumber
{
    MessageRandomNumber message;
    message.message.messageType = kMessageTypeRandomNumber;
    message.randomNumber = ourRandom;
    NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageRandomNumber)];
    [self sendData:data];
}

- (void)sendGameBegin {
    
    MessageGameBegin message;
    message.message.messageType = kMessageTypeGameBegin;
    NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageGameBegin)];    
    [self sendData:data];
    
}
- (void)sendMove {
    
    MessageMove message;
    message.message.messageType = kMessageTypeMove;
    NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageMove)];    
    [self sendData:data];
    
}

- (void)sendGameOver:(BOOL)player1Won {
    
    MessageGameOver message;
    message.message.messageType = kMessageTypeGameOver;
    message.player1Won = player1Won;
    NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageGameOver)];    
    [self sendData:data];
    
}

- (void)setGameState:(GameState)state {
    
    gameState = state;
    if (gameState == kGameStateWaitingForMatch) {
        [debugLabel setString:@"Waiting for match"];
    } else if (gameState == kGameStateWaitingForRandomNumber) {
        [debugLabel setString:@"Waiting for rand #"];
    } else if (gameState == kGameStateWaitingForStart) {
        [debugLabel setString:@"Waiting for start"];
    } else if (gameState == kGameStateActive) {
        [debugLabel setString:@"Active"];
    } else if (gameState == kGameStateDone) {
        [debugLabel setString:@"Done"];
    } 
    
}
#pragma mark Set Player Name
- (void) setupStringWithOtherPlayerID:(NSString*)playerID
{
    NSLog(@"(NSString*)playerID>>>>>%@",playerID);
    GKPlayer* player3 = [[GCHelper sharedInstance].playersDict objectForKey:playerID];
    NSLog(@"player3.alias>>>>>%@",player3.alias);
    if(isPlayer1)
    {
        player1Label = [[CCLabelBMFont alloc] initWithString:[GKLocalPlayer localPlayer].alias
                                                     fntFile:@"Arial.fnt"];
        [self addChild:player1Label];
        
        GKPlayer* player = [[GCHelper sharedInstance].playersDict objectForKey:playerID];
        player2Label = [[CCLabelBMFont alloc] initWithString:player.alias 
                                                     fntFile:@"Arial.fnt"];
        [self addChild:player2Label];
        
    }else
    {
        player2Label = [[CCLabelBMFont alloc] initWithString:[GKLocalPlayer localPlayer].alias
                                                     fntFile:@"Arial.fnt"];
        [self addChild:player2Label];
        
        GKPlayer* player = [[GCHelper sharedInstance].playersDict objectForKey:playerID];
        player1Label = [[CCLabelBMFont alloc] initWithString:player.alias 
                                                     fntFile:@"Arial.fnt"];
        [self addChild:player1Label];

    }
}
#pragma mark Init Game
+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	HelloWorldLayer *layer = [HelloWorldLayer node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
-(id) init
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super" return value
	if( (self=[super init])) {
		
        // Get win size
        CGSize winSize = [CCDirector sharedDirector].winSize;
        
        // Add background
        CCSprite *bg = [CCSprite spriteWithFile:@"bg.png"];
        bg.anchorPoint = CGPointZero;
        [self addChild:bg z:-2];
        
        // Add batch node
        batchNode = [CCSpriteBatchNode batchNodeWithFile:@"CatSmash.png"];
        [self addChild:batchNode z:-1];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"CatSmash.plist"];
        
        // Create sprite for cat
        float catYOffset = 35;
        cat = [CCSprite spriteWithSpriteFrameName:@"cat_stand_1.png"];
        cat.position = ccp(winSize.width-cat.contentSize.width/2, cat.contentSize.height/2 + catYOffset);
        [batchNode addChild:cat z:1];
        
        // Create sprites for each player
        player1 = [[[PlayerSprite alloc] initWithType:kPlayerSpriteDog] autorelease];
        player2 = [[[PlayerSprite alloc] initWithType:kPlayerSpriteKid] autorelease];
        [batchNode addChild:player1 z:2];
        [batchNode addChild:player2 z:0];
        
        // Set positions of each player
        float maxWidth = MAX(player1.contentSize.width, player2.contentSize.width);        
        float playersYOffset = 50;     
        float playersXOffset = -(maxWidth-MIN(player1.contentSize.width, player2.contentSize.width)); 
        player1.position = ccp(maxWidth-player1.contentSize.width + player1.contentSize.width/2 + playersXOffset, 
                               player1.contentSize.height/2);
        player1.moveTarget = player1.position;
        player2.position = ccp(maxWidth-player2.contentSize.width + player2.contentSize.width/2 + playersXOffset, 
                               player1.contentSize.height/2 + playersYOffset);
        player2.moveTarget = player2.position;
        
        // Enable touches
        self.isTouchEnabled = YES;
        
        // Set up main loop to check for wins
        [self scheduleUpdate];       
        
        // Add a debug label to the scene to display current game state
        debugLabel = [CCLabelBMFont labelWithString:@"" fntFile:@"Arial.fnt"];
        debugLabel.position = ccp(winSize.width/2, 300);
        [self addChild:debugLabel];
        
        // Set ourselves as player 1 and the game to active
        isPlayer1 = YES;
        
        ourRandom = arc4random();
        [self setGameState:kGameStateWaitingForMatch];
        
        AppDelegate * delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;  
        
        [[GCHelper sharedInstance] findMathWithMinPlayers:2
                                               maxPlayers:2 
                                           viewController:delegate.viewController
                                                 delegate:self];
        
        //Leaderboard and Achievements
        self.currentLeaderBoard = kLeaderboardID;        		
	}
	return self;
}

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
       

    if (gameState != kGameStateActive) return;
    [self sendMove];
    
    // Move the appropriate player forward a bit
    if (isPlayer1) {
        [player1 moveForward];
    } else {
        [player2 moveForward];
    }
}

- (void)restartTapped:(id)sender {
    
    // Reload the current scene
    [[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipX transitionWithDuration:0.5 scene:[HelloWorldLayer scene]]];
    
}

// Helper code to show a menu to restart the level
// From Cat Nap tutorial
- (void)endScene:(EndReason)endReason {
        
    if (gameState == kGameStateDone) return;
    [self setGameState:kGameStateDone];
    
    CGSize winSize = [CCDirector sharedDirector].winSize;
    
    NSString *message;
    if (endReason == kEndReasonWin) {
        message = @"You win!";
    } else if (endReason == kEndReasonLose) {
        message = @"You lose!";
    }
    
    CCLabelBMFont *label = [CCLabelBMFont labelWithString:message fntFile:@"Arial.fnt"];
    label.scale = 0.1;
    label.position = ccp(winSize.width/2, 220);
    [self addChild:label];
    
    CCLabelBMFont *restartLabel = [CCLabelBMFont labelWithString:@"Restart"
                                                         fntFile:@"Arial.fnt"];    
    
    CCMenuItemLabel *restartItem = [CCMenuItemLabel itemWithLabel:restartLabel
                                                           target:self 
                                                         selector:@selector(restartTapped:)];
    restartItem.scale = 0.1;
    restartItem.position = ccp(winSize.width/2, 180);
    
    CCLabelBMFont *leaderBoardLabel = [CCLabelBMFont labelWithString:@"LeaderBoard"
                                                             fntFile:@"Arial.fnt"];  
    CCMenuItemLabel *leaderBoardItem = [CCMenuItemLabel itemWithLabel:leaderBoardLabel 
                                                               target:self 
                                                             selector:@selector(showLeaderBoard:)];
    leaderBoardItem.scale = 0.1;
    leaderBoardItem.position = ccp(winSize.width/2, 140);

    CCLabelBMFont *achievementLabel = [CCLabelBMFont labelWithString:@"Achievements"
                                                             fntFile:@"Arial.fnt"];
    CCMenuItemLabel *achievementItem = [CCMenuItemLabel itemWithLabel:achievementLabel
                                                               target:self 
                                                             selector:@selector(showAchievements:)];
    achievementItem.scale = 0.1;
    achievementItem.position = ccp(winSize.width/2, 100);
    
    
    CCLabelBMFont *reportScoreLabel = [CCLabelBMFont labelWithString:@"Report Score"
                                                             fntFile:@"Arial.fnt"];
    CCMenuItemLabel *reportScoreItem = [CCMenuItemLabel itemWithLabel:reportScoreLabel
                                                               target:self 
                                                             selector:@selector(submitScore:)];
    reportScoreItem.scale = 0.1;
    reportScoreItem.position = ccp(winSize.width/2, 60);
    
    CCLabelBMFont *reportAchievementLabel = [CCLabelBMFont labelWithString:@"Report Achievement"
                                                             fntFile:@"Arial.fnt"];
    CCMenuItemLabel *reportAchievementItem = [CCMenuItemLabel itemWithLabel:reportAchievementLabel
                                                               target:self 
                                                             selector:@selector(submitAchievements:)];
    reportAchievementItem.scale = 0.1;
    reportAchievementItem.position = ccp(winSize.width/2, 20);
    CCMenu *menu;
    if (endReason == kEndReasonWin) {
        menu = [CCMenu menuWithItems:restartItem,leaderBoardItem,achievementItem,reportScoreItem,reportAchievementItem, nil];
    } else if (endReason == kEndReasonLose) {
        menu = [CCMenu menuWithItems:restartItem,leaderBoardItem,achievementItem, nil];
    }
    menu.position = CGPointZero;
    [self addChild:menu];
    
    [restartItem runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    [leaderBoardItem runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
     [achievementItem runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    [reportScoreItem runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    [reportAchievementItem runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    [label runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    
    if (isPlayer1) {
        if (endReason == kEndReasonWin) {
            [self sendGameOver:true];
        } else if (endReason == kEndReasonLose) {
            [self sendGameOver:false];
        }
    }

        
}

- (void)update:(ccTime)dt {
    //Set position player name label
    player1Label.position = player1.position;
    player2Label.position = player2.position;
    
    // Makes it so only player 1 checks for game over conditions
    if (!isPlayer1) return;
    
    // Check to see if player 1 or player 2 has passed the cat's center
    if (player1.position.x + player1.contentSize.width/2 > cat.position.x) {
        if (isPlayer1) {
            [self endScene:kEndReasonWin];
        } else {
            [self endScene:kEndReasonLose];
        }
    } else if (player2.position.x + player2.contentSize.width/2 > cat.position.x) {
        if (isPlayer1) {
            [self endScene:kEndReasonLose];
        } else {
            [self endScene:kEndReasonWin];
        }
    }

}



#pragma mark GCHelperDelegate
- (void)tryStartGame {
    
    if (isPlayer1 && gameState == kGameStateWaitingForStart) {
        [self setGameState:kGameStateActive];
        [self sendGameBegin];
        
        //Set player name
        [self setupStringWithOtherPlayerID:otherPlayerID];
    }
    
}
- (void)matchStarted {    
    CCLOG(@"Match started"); 
    if(receivedRandom)
    {
        [self  setGameState:kGameStateWaitingForStart];
    }else
    {
        [self setGameState:kGameStateWaitingForRandomNumber];
    }
    //send random number
    [self sendRandomNumber];
    //try to start game
    [self tryStartGame];
    
    [[GCHelper sharedInstance] loadAchievements];
}

- (void)matchEnded {    
    CCLOG(@"Match ended"); 
    
    [[GCHelper sharedInstance].match disconnect];
    [GCHelper sharedInstance].match = nil;
    [self endScene:kEndReasonDisconnect];
}

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
    CCLOG(@"Received data");
    if(otherPlayerID == nil)
    {
        otherPlayerID = [playerID retain];
    }
    Message *message = (Message*)[data bytes];
    if(message->messageType == kMessageTypeRandomNumber)
    {
        MessageRandomNumber* messageInit = (MessageRandomNumber*)[data bytes];
        NSLog(@"Received random number: %ud, ours %ud", messageInit->randomNumber,ourRandom);
        bool tie = false;
        
        if (messageInit->randomNumber == ourRandom) {
            NSLog(@"TIE!");
            tie = true;
            ourRandom = arc4random();
            [self sendRandomNumber];
        }else if(ourRandom > messageInit->randomNumber)
        {
            NSLog(@"We are player 1");
            isPlayer1 = YES;
        }else
        {
            NSLog(@"We are player 2");
            isPlayer1 = NO;
        }
        
        if(!tie)
        {
            receivedRandom = YES;
            if (gameState == kGameStateWaitingForRandomNumber) {
                [self setGameState:kGameStateWaitingForStart];
            }
            [self tryStartGame];
        }
    }else if (message->messageType == kMessageTypeGameBegin) {        
        //Set player name
        [self setupStringWithOtherPlayerID:otherPlayerID];
        
        [self setGameState:kGameStateActive];    
        
    }else if (message->messageType == kMessageTypeMove) {     
        
        CCLOG(@"Received move");
        
        if (isPlayer1) {
            [player2 moveForward];
        } else {
            [player1 moveForward];
        }        
    }else if (message->messageType == kMessageTypeGameOver) {        
        
        MessageGameOver * messageGameOver = (MessageGameOver *) [data bytes];
        CCLOG(@"Received game over with player 1 won: %d", messageGameOver->player1Won);
        
        if (messageGameOver->player1Won) {
            [self endScene:kEndReasonLose];    
        } else {
            [self endScene:kEndReasonWin];    
        }
        
    }    
}
#pragma mark LeaderBoard and Achievements
- (void)showLeaderBoard:(id)sender
{
    GKLeaderboardViewController* leaderboardViewCtrl = [[GKLeaderboardViewController alloc] init];
    if(leaderboardViewCtrl != NULL)
    {        
        rootViewCtrl = [[UIViewController alloc] init];
        [rootViewCtrl.view setFrame:CGRectMake(0.0, 0.0, 480, 320)];
        
        leaderboardViewCtrl.category = self.currentLeaderBoard;
        leaderboardViewCtrl.timeScope = GKLeaderboardTimeScopeWeek;
        leaderboardViewCtrl.leaderboardDelegate = self;
        [[[[CCDirector sharedDirector] openGLView] window]addSubview:rootViewCtrl.view];
        
        
        [rootViewCtrl presentModalViewController:leaderboardViewCtrl animated:NO];
        
    }
}

-(void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
    [rootViewCtrl dismissModalViewControllerAnimated:NO];
    [rootViewCtrl.view removeFromSuperview];
    
    [[CCDirector sharedDirector] replaceScene:[HelloWorldLayer node]];

    [viewController release];
    
    
}

- (void)showAchievements:(id)sender
{
    GKAchievementViewController* achievementViewCtrl = [[GKAchievementViewController alloc] init];
    if(achievementViewCtrl != NULL)
    {
        rootViewCtrl = [[UIViewController alloc] init];
        [rootViewCtrl.view setFrame:CGRectMake(0.0, 0.0, 480, 320)];
        
        achievementViewCtrl.achievementDelegate = self;
        
        [[[[CCDirector sharedDirector] openGLView] window]addSubview:rootViewCtrl.view];
        [rootViewCtrl presentModalViewController:achievementViewCtrl animated:NO];
    }
}

- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
    [rootViewCtrl dismissModalViewControllerAnimated:NO];
    [rootViewCtrl.view removeFromSuperview];
    
    [[CCDirector sharedDirector] replaceScene:[HelloWorldLayer node]];
    
    [viewController release];
}

- (void)submitScore:(id)sender
{
    [[GCHelper sharedInstance] getCurrentLeaderboardScore:self.currentLeaderBoard
                                      withCalculatedScore:1];
    
//    [[GCHelper sharedInstance] reportScore:99 forCategory:self.currentLeaderBoard];
}
- (void)scoreReported:(NSError *)error
{
    if(error == NULL)
    {
        NSLog(@"Score report Successful...");
        [[GCHelper sharedInstance] reloadHighScoresForCategory: self.currentLeaderBoard];
    }else
    {
        NSLog(@"Score report Failed...");
    }
}
- (void) reloadScoresComplete: (GKLeaderboard*) leaderBoard error: (NSError*) error
{
    if(error == NULL)
    {
        NSLog(@"reloadScoresComplete Successful...");
    }else
    {
        NSLog(@"reloadScoresComplete Failed...%@",error);
    }
}
- (void) submitAchievements:(id)sender{
    [[GCHelper sharedInstance] loadAchievements];
    
    GKAchievement* achi = [[GCHelper sharedInstance] getAchievementForIdentifier:kAchievementGoal1];   
    
    NSLog(@">>>>>>>>>>>>percentComplete>>>>>>>>>>>>>>>>>>%f",achi.percentComplete);
    float percent = 100.0 * (achi.percentComplete * 5 / 100 + 1) / 5 ;
    NSLog(@">>>>>>persent= %f",percent);
    
    [[GCHelper sharedInstance] reportAchievementIdentifier:kAchievementGoal1 percentComplete:percent];
}
- (void)submitAchievementsComplete:(GKAchievement *)achievement error:(NSError *)error
{
    [[GCHelper sharedInstance] loadAchievements];
    GKAchievement* achi = [[GCHelper sharedInstance] getAchievementForIdentifier:kAchievementGoal1];  
    NSLog(@">>>>>>>>>>>>percentComplete>>>kAchievementWin5Times>>>>>>>>>>>>>>>%f",achi.percentComplete);
    NSLog(@">>>>>>>>error>>>>>>>>>>>>%@",error);
}

- (void)inviteReceived {
    [self restartTapped:nil];    
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
	[otherPlayerID release];
    otherPlayerID = nil;
	
    [super dealloc];
}
@end
